package com.qunar.dyds.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.qunar.base.meerkat.util.DateUtil;
import com.qunar.base.meerkat.util.StringUtil;
import com.qunar.base.meerkat.web.codelist.MappedCodeListLoader;
import com.qunar.common.admin.constant.WebConstants;
import com.qunar.dyds.dto.ListObject;
import com.qunar.dyds.entity.Report;
import com.qunar.dyds.entity.ReportStatus;

@Controller("report")
public class ReportController extends AbstractController {

    @RequestMapping(value = "list")
    public ModelAndView list(@RequestParam(value = "inviteCode", required = false) String inviteCode,
            @RequestParam(value = "mobile", required = false) String mobile,
            @RequestParam(value = "status", required = false) Integer status,
            @RequestParam(value = "startIndex", required = false, defaultValue = "0") int startIndex,
            @RequestParam(value = "row", required = false, defaultValue = WebConstants.DEFAULT_PAGE_SIZE_STR) int row) {

        Map<String, Object> cond = new HashMap<String, Object>();
        cond.put("inviteCode", inviteCode);
        cond.put("mobile", mobile);
        cond.put("status", status);

        int totalCount = reportService.getCount(cond);

        List<Report> beans = reportService.search(cond, startIndex, row);

        // 绑定结果列表
        ListObject lstObj = new ListObject(startIndex, row, totalCount, beans);
        ModelAndView view = new ModelAndView("report/list");
        view.addObject("lstObj", lstObj);
        view.addObject("cond", cond);

        return view;
    }

    @RequestMapping(value = "detail", method = RequestMethod.GET)
    public ModelAndView detail(@RequestParam("id") Integer id) {

        Report report = reportService.get(id);
        return new ModelAndView("report/detail", "item", report);
    }


    @RequestMapping(value = "accept", method = RequestMethod.GET)
    public String accept(@RequestParam("id") Integer id,
            @RequestParam(value = "forward", required = false) String forward) {

        return updateStatus(id, ReportStatus.ACCEPTED, forward);
    }

    @RequestMapping(value = "delete", method = RequestMethod.GET)
    public String delete(@RequestParam("id") Integer id,
            @RequestParam(value = "forward", required = false) String forward) {

        return updateStatus(id, ReportStatus.DELETED, forward);
    }

    protected String updateStatus(int id, int status, String forward) {

        Report report = new Report();
        report.setId(id);
        report.setStatus(status);
        report.setUpdated(new Date());

        try {
            reportService.update(report);
        } catch (Exception e) {
            logger.error("update status failed. e={}, id={}", e, id);
        }

        if (!StringUtil.isEmpty(forward)) {
            return "redirect:" + forward;
        }

        return "redirect:/report/list.htm";
    }

    @RequestMapping(value = "export", method = RequestMethod.GET)
    public void export(@RequestParam(value = "inviteCode", required = false) String inviteCode,
            @RequestParam(value = "mobile", required = false) String mobile,
            @RequestParam(value = "status", required = false) Integer status, HttpServletResponse response) {

        Map<String, Object> cond = new HashMap<String, Object>();
        cond.put("inviteCode", inviteCode);
        cond.put("mobile", mobile);
        cond.put("status", status);

        // 查询记录列表
        List<Report> beans = reportService.search(cond);

        // 下载文件
        String filename = getDownloadFileName(cond);
        response.setContentType("application/vnd.ms-excel");
        response.addHeader("Content-Disposition", "attachment;   filename=\"" + filename + "\"");

        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            export(outputStream, beans);
            response.flushBuffer();
        } catch (Exception e) {
            logger.error("export excel failed, e={}, cond={}", e, cond);
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                }
            }
        }
    }

    @Resource(name = "reportStatusLoader")
    protected MappedCodeListLoader reportStatusLoader;

    /**
     * 下载文件名
     * 
     * @param cond 查询条件
     * @return
     */
    protected String getDownloadFileName(Map<String, Object> cond) {
        Iterator<String> iter = cond.keySet().iterator();
        StringBuilder sb = new StringBuilder("投诉信息_");
        while (iter.hasNext()) {
            String key = iter.next();
            Object value = cond.get(key);
            if (value == null || "".equals(value)) {
                continue;
            }
            if ("status".equals(key)) {
                sb.append(reportStatusLoader.getCodeListMap().get(value.toString()));
            } else {
                sb.append(value);
            }
            sb.append("_");
        }
        String timestamp = DateUtil.format(new Date(), DateUtil.PATTERN_YYYY_MM_DD_HH_MM_SS);

        return StringUtil.encodeURL(sb.toString()) + timestamp + ".xls";
    }

    protected void export(OutputStream outputStream, List<Report> beans) throws IOException, RowsExceededException,
            WriteException {

        // 工作表
        WritableWorkbook workbook = Workbook.createWorkbook(outputStream);

        // 工作表单
        WritableSheet sheet = workbook.createSheet("投诉信息", 0);
        // 设置表头
        sheet.addCell(new Label(0, 0, "ID"));
        sheet.addCell(new Label(1, 0, "被投诉报名序号"));
        sheet.addCell(new Label(2, 0, "被投诉人"));
        sheet.addCell(new Label(3, 0, "投诉人"));
        sheet.addCell(new Label(4, 0, "投诉人电话"));
        sheet.addCell(new Label(5, 0, "投诉内容"));
        sheet.addCell(new Label(6, 0, "投诉状态"));
        sheet.addCell(new Label(7, 0, "创建时间"));
        sheet.addCell(new Label(8, 0, "更新时间"));

        int row = 0;
        for (int i = 0; i < beans.size(); i++) {
            Report item = beans.get(i);
            row = i + 1;

            sheet.addCell(new Label(0, row, String.valueOf(item.getId())));
            sheet.addCell(new Label(1, row, item.getInviteCode()));
            sheet.addCell(new Label(2, row, item.getUsername()));
            sheet.addCell(new Label(3, row, item.getName()));
            sheet.addCell(new Label(4, row, item.getMobile()));
            sheet.addCell(new Label(5, row, item.getContent()));
            sheet.addCell(new Label(6, row, reportStatusLoader.getCodeListMap().get(item.getStatus())));
            sheet.addCell(new Label(7, row, DateUtil.format(item.getCreated(), DateUtil.PATTERN_YYYY_MM_DD_HH_MM_SS)));
            sheet.addCell(new Label(8, row, DateUtil.format(item.getUpdated(), DateUtil.PATTERN_YYYY_MM_DD_HH_MM_SS)));
        }

        workbook.write();
        workbook.close();
    }
}
